package com.yunfeisoft.business.dao.impl.postgres;

import com.applet.base.ServiceDaoImpl;
import com.applet.sql.builder.SelectBuilder;
import com.applet.sql.builder.WhereBuilder;
import com.applet.sql.mapper.DefaultRowMapper;
import com.applet.utils.Page;
import com.yunfeisoft.business.dao.inter.WarehouseProductDao;
import com.yunfeisoft.business.model.Product;
import com.yunfeisoft.business.model.Warehouse;
import com.yunfeisoft.business.model.WarehouseProduct;
import com.yunfeisoft.enumeration.YesNoEnum;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

/**
 * ClassName: WarehouseProductDaoImpl
 * Description: 仓库商品信息Dao实现
 * Author: Jackie liu
 * Date: 2020-08-04
 */
@Repository
public class WarehouseProductDaoImpl extends ServiceDaoImpl<WarehouseProduct, String> implements WarehouseProductDao {

    @Override
    public Page<WarehouseProduct> queryPage(Map<String, Object> params) {
        WhereBuilder wb = new WhereBuilder();
        wb.setOrderByWithDesc("p.createTime");
        if (params != null) {
            initPageParam(wb, params);
            wb.andEquals("p.orgId", params.get("orgId"));
            wb.andEquals("p.code", params.get("productCode"));
            wb.andEquals("wp.warehouseId", params.get("warehouseId"));
            wb.andEquals("wp.productId", params.get("productId"));
            wb.andEquals("p.isDel", YesNoEnum.NO_CANCEL.getValue());
            wb.andFullLike("p.name", params.get("productName"));
            wb.andFullLike("p.pinyinCode", params.get("pinyinCode"));

            String warnType = (String) params.get("warnType");
            if ("outStock".equals(warnType)) {
                wb.andCustomSQL("WP.SHORTAGE_LIMIT_ - WP.STOCK_ >= 0", null);
            } else if ("backlog".equals(warnType)) {
                wb.andCustomSQL("WP.STOCK_ - WP.BACKLOG_LIMIT_ >= 0", null);
            } else if ("nq0".equals(warnType)) {
                wb.andNotEquals("wp.stock", 0);
            } else if ("eq0".equals(warnType)) {
                wb.andEquals("wp.stock", 0);
            } else if ("gt0".equals(warnType)) {
                wb.andGreaterThan("wp.stock", 0);
            } else if ("lt0".equals(warnType)) {
                wb.andLessThan("wp.stock", 0);
            }

            String namePinyin = (String) params.get("namePinyin");
            if (StringUtils.isNotBlank(namePinyin)) {
                wb.andGroup()
                        .orFullLike("p.pinyinCode", StringUtils.upperCase(namePinyin))
                        .orFullLike("p.name", namePinyin)
                        .orFullLike("p.code", namePinyin)
                        .andGroup();
            }
        }

        SelectBuilder builder = getSelectBuilder("wp");
        builder.column("w.name as warehouseName")
                .column("p.code as productCode")
                .column("p.name as productName")
                .column("p.standard as productStandard")
                .column("p.unit as productUnit")
                .column("p.buyPrice as buyPrice")
                .column("p.salePrice as salePrice")
                .column("p.memberPrice as memberPrice")
                .column("p.tradePrice as tradePrice")
                .join(Warehouse.class).alias("w").on("wp.warehouseId = w.id").build()
                .join(Product.class).alias("p").on("wp.productId = p.id").build();

        return queryPage(builder.getSql(), wb);
    }

    @Override
    public List<WarehouseProduct> queryList(Map<String, Object> params) {
        WhereBuilder wb = new WhereBuilder();
        if (params != null) {
            wb.andEquals("p.orgId", params.get("orgId"));
            wb.andEquals("p.code", params.get("productCode"));
            wb.andEquals("wp.warehouseId", params.get("warehouseId"));
            wb.andEquals("wp.productId", params.get("productId"));
            wb.andFullLike("p.name", params.get("productName"));

            String warnType = (String) params.get("warnType");
            if ("outStock".equals(warnType)) {
                wb.andCustomSQL("WP.SHORTAGE_LIMIT_ - WP.STOCK_ >= 0", null);
            } else if ("backlog".equals(warnType)) {
                wb.andCustomSQL("WP.STOCK_ - WP.BACKLOG_LIMIT_ >= 0", null);
            }
        }

        SelectBuilder builder = getSelectBuilder("wp");
        builder.column("w.name as warehouseName")
                .column("p.code as productCode")
                .column("p.name as productName")
                .column("p.standard as productStandard")
                .column("p.unit as productUnit")
                .column("p.buyPrice as buyPrice")
                .column("p.salePrice as salePrice")
                .column("p.memberPrice as memberPrice")
                .column("p.tradePrice as tradePrice")
                .join(Warehouse.class).alias("w").on("wp.warehouseId = w.id").build()
                .join(Product.class).alias("p").on("wp.productId = p.id").build();

        return query(builder.getSql(), wb);
    }

    @Override
    public WarehouseProduct loadSingle(String productId, String warehouseId) {
        WhereBuilder wb = new WhereBuilder();
        wb.andEquals("productId", productId);
        wb.andEquals("warehouseId", warehouseId);

        SelectBuilder builder = getSelectBuilder("wp");
        builder.column("p.buyPrice as buyPrice")
                .join(Product.class).alias("p").on("wp.productId = p.id").build();

        List<WarehouseProduct> list = query(builder.getSql(), wb);
        return CollectionUtils.isEmpty(list) ? null : list.get(0);
    }

    @Override
    public WarehouseProduct queryStockSum(String productId) {
        String sql = "SELECT SUM(STOCK_) AS STOCK_, SUM(INIT_STOCK_) AS INIT_STOCK_ FROM TT_WAREHOUSE_PRODUCT WHERE PRODUCT_ID_ = ?";
        List<WarehouseProduct> list = jdbcTemplate.query(sql, new Object[]{productId}, new DefaultRowMapper<WarehouseProduct>(WarehouseProduct.class));
        return CollectionUtils.isEmpty(list) ? new WarehouseProduct() : list.get(0);
    }
}